//
//  String.swift
//  vr_web
//
//  Created by 李旭峰 on 2020/7/13.
//


import Foundation
import UIKit
import CommonCrypto

extension String {
    static func SwitchToString(_ value:Any?) -> String?{
        switch value {
        case is NSNull:return nil
        case is CustomStringConvertible:
            return (value as! CustomStringConvertible).description
        default:break
        }
        return nil
    }
    
    
    func slicing(_ from:Int,_ to:Int) -> String{
        let selfStr = self.description
        if selfStr.count <= max(from, 0) {
            return ""
        }
        let `to` = min(selfStr.count, to)
        let startIndex = selfStr.index(selfStr.startIndex, offsetBy: from)
        let endIndex = selfStr.index(selfStr.startIndex, offsetBy: to)
        let subStr = selfStr[startIndex..<endIndex]
        return String(subStr)
    }
    /// 字符串长度
    var length: Int {
        return self.count
    }
    
    /**
     截取数字字符串，小数位大于8位则截取小数8位后的数字
     
     - parameter string: 要截取的字符串
     
     - returns: 返回新的字符串
     */
    func subString(def:Int = 8) -> String{
        let stringArr = self.components(separatedBy: ".")
        var newString = ""
        if stringArr.count == 2 {
            if stringArr[1].length > def{
                newString = String(format: "%.\(def)f", (self.toDouble()))
            }else{
                newString = self
            }
            if newString.toDouble() == 0{
                newString = "0"
            }
        }else{
            newString = self
        }
        
        
        
        return newString
    }
    
    /**
     计算文字的高度
     
     - parameter font:
     - parameter size:
     
     - returns:
     */
    func textSizeWithFont(_ font: UIFont, constrainedToSize size:CGSize) -> CGSize {
        var textSize:CGSize!
        let newStr = NSString(string: self)
        if size.equalTo(CGSize.zero) {
            let attributes = [NSAttributedString.Key.font: font]
            textSize = newStr.size(withAttributes: attributes)
        } else {
            let option = NSStringDrawingOptions.usesLineFragmentOrigin
            let attributes = [NSAttributedString.Key.font: font]
            let stringRect = newStr.boundingRect(with: size, options: option, attributes: attributes, context: nil)
            textSize = stringRect.size
        }
        return textSize
    }
    
    // MARK: Trim API
    
    /// 去掉字符串前后的空格，根据参数确定是否过滤换行符
    ///
    /// - parameter trimNewline 是否过滤换行符，默认为false
    ///
    /// - returns:   处理后的字符串
    func trim(_ trimNewline: Bool = false) ->String {
        if trimNewline {
            return self.trimmingCharacters(in: .whitespacesAndNewlines)
        }
        
        return self.trimmingCharacters(in: .whitespaces)
    }
    
    /**
     * 去除字符串左右的空格和换行，直到左右都没有任何空格和换行或者变成空字符串了
     */
    func trimBlankSpaceAndLineFeeds() -> String {
        
        let result = self.trimmingCharacters(in: .whitespacesAndNewlines)
        
        if result.hasPrefix(" ") || result.hasSuffix(" ") || result.hasPrefix("\n") || result.hasSuffix("\n") {
            
            return result.trimBlankSpaceAndLineFeeds()
        } else {
            
            return result
        }
    }
    
    // MARK: Substring API
    
    /// 获取子串的起始位置。
    ///
    /// - parameter substring 待查找的子字符串
    ///
    /// - returns:  如果找不到子串，返回NSNotFound，否则返回其所在起始位置
    func location(_ substring: String) ->Int {
        return (self as NSString).range(of: substring).location
    }
    
    /// 根据起始位置和长度获取子串。
    ///
    /// - parameter location  获取子串的起始位置
    /// - parameter length    获取子串的长度
    ///
    /// - returns:  如果位置和长度都合理，则返回子串，否则返回nil
    func substring(_ location: Int, length: Int) ->String? {
        if location < 0 {
            return self.substring(0, length: length)
        }
        if location < 0 && location >= self.length {
            return nil
        }
        
        if length <= 0 || length > self.length {
            return nil
        }
        
        let startIndex = self.index(self.startIndex, offsetBy: location)
        let endIndex = self.index(startIndex, offsetBy: length)
        let subString = self[startIndex..<endIndex]
        
        return String(subString)
    }
    
    /// 根据下标获取对应的字符。若索引正确，返回对应的字符，否则返回nil
    ///
    /// - parameter index 索引位置
    ///
    /// - returns: 如果位置正确，返回对应的字符，否则返回nil
    subscript(index: Int) ->Character? {
        get {
            if let str = substring(index, length: 1) {
                return Character(str)
            }
            
            return nil
        }
    }
    
    /// 判断字符串是否包含子串。
    ///
    /// - parameter substring 子串
    ///
    /// - returns:  如果找到，返回true,否则返回false
    func isContain(_ substring: String) ->Bool {
        return (self as NSString).contains(substring)
    }
    
    // MARK: Alphanum API
    
    /// 判断字符串是否全是数字组成
    ///
    /// - returns:  若为全数字组成，返回true，否则返回false
    func isOnlyNumbers() ->Bool {
        let set = CharacterSet.decimalDigits.inverted
        let range = (self as NSString).rangeOfCharacter(from: set)
        let flag = range.location != NSNotFound
        return flag
    }
    
    /// 判断字符串是否全是字母组成
    ///
    /// - returns:  若为全字母组成，返回true，否则返回false
    func isOnlyLetters() ->Bool {
        let set = CharacterSet.letters.inverted
        let range = (self as NSString).rangeOfCharacter(from: set)
        
        return range.location != NSNotFound
    }
    
    /// 判断字符串是否全是字母和数字组成
    ///
    /// - returns:  若为全字母和数字组成，返回true，否则返回false
    func isAlphanum() ->Bool {
        let set = CharacterSet.alphanumerics.inverted
        let range = (self as NSString).rangeOfCharacter(from: set)
        
        return range.location != NSNotFound
    }
    
    // MARK: Validation API
    
    /// 判断字符串是否是有效的邮箱格式
    ///
    /// - returns:  若为有效的邮箱格式，返回true，否则返回false
    func isValidEmail() ->Bool {
        let regEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"
        let predicate = NSPredicate(format: "SELF MATCHES %@", regEx)
        
        return predicate.evaluate(with: self)
    }
    
    // MARK: Format API
    
    /**
     
     插入字符分隔字符串
     - parameter char:     要插入的字符
     - parameter interval: 间隔数
     */
    func insertCharByInterval(_ char: String, interval: Int) -> String {
        var text = self as NSString
        var newString = ""
        while (text.length > 0) {
            let subString = text.substring(to: min(text.length,interval))
            newString = newString + subString
            if (subString.length == interval) {
                newString = newString + char
            }
            text = text.substring(from: min(text.length,interval)) as NSString
        }
        return newString
    }
    
    
    // MARK: CAST TO OTHER TYPE API
    
    /// 转double
    ///
    /// - Parameters:
    ///   - def: 默认值
    ///   - decimal: 舍弃小数位精度
    /// - Returns:
    func toDouble(_ def: Double = 0.0, decimal: Int? = nil) -> Double {
        if !self.isEmpty {
            var doubleValue = Double(self) ?? def
            if let dec = decimal {
                doubleValue = doubleValue.f(places: dec)
            }
            return doubleValue
        } else {
            return def
        }
    }
    
    func toFloat(_ def: Float = 0.0) -> Float {
        if !self.isEmpty {
            return Float(self) ?? def
        } else {
            return def
        }
    }
    
    func toInt(_ def: Int = 0) -> Int {
        if !self.isEmpty {
            return Int(self)!
        } else {
            return def
        }
    }
    
    func toBool(_ def: Bool = false) -> Bool {
        if !self.isEmpty {
            let value = Int(self)!
            if value > 0 {
                return true
            } else {
                return false
            }
        } else {
            return def
        }
    }
    
    /// 根据文字内容，最大宽度，字体大小计算出文字所占的高度
    static func getStrHeight(text: NSString, width: CGFloat, font: UIFont = UIFont.systemFont(ofSize: 14)) -> CGFloat {
        
        let rect = text.boundingRect(with: CGSize(width: width, height: CGFloat(MAXFLOAT)), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font : font], context: nil)
        
        return ceil(rect.size.height)
    }
    
    /// 根据文字内容，最大高度，字体大小计算出文字所占的宽度
    static func getStrHeight(text: NSString, width: CGFloat, attributes: [NSAttributedString.Key : Any]?) -> CGFloat {
        
        let rect = text.boundingRect(with: CGSize(width: width, height: CGFloat(MAXFLOAT)), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: attributes, context: nil)
        
        return ceil(rect.size.height)
    }
    
    /// 根据文字内容，最大高度，字体大小计算出文字所占的宽度
    static func getStrWidth(text: NSString, height: CGFloat, font: UIFont = UIFont.systemFont(ofSize: 14)) -> CGFloat {
        
        let rect = text.boundingRect(with: CGSize(width: CGFloat(MAXFLOAT), height: height), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font : font], context: nil)
        
        return ceil(rect.size.width)
    }
    
    /// 判断输入的字符是否是emoji表情
    static func isEmoji(from: String) -> Bool{
        func disable_emoji(text:String) -> String{
            
            let regex = try? NSRegularExpression(pattern: "[^\\u0020-\\u007E\\u00A0-\\u00BE\\u2E80-\\uA4CF\\uF900-\\uFAFF\\uFE30-\\uFE4F\\uFF00-\\uFFEF\\u0080-\\u009F\\u2000-\\u201f\r\n]", options: NSRegularExpression.Options.caseInsensitive)
            
            let modifiedString = regex!.stringByReplacingMatches(in: text, options: NSRegularExpression.MatchingOptions(), range: NSMakeRange(0, text.utf16.count), withTemplate: "")
            
            return modifiedString
        }
        
        // 判断是不是系统键盘输入的数字➋➌➍➎➏➐➑➒，这种情况要放开
        let otherStr = "➋➌➍➎➏➐➑➒"
        if otherStr.range(of: from) != nil {
            return false
        } else {
            // 当输入的是表情，那么不进行替换
            return from != disable_emoji(text: from)
        }
    }
    
    /**
     金额格式化
     */
    func moneyFormat() -> String {
        
        let numberFormatter = NumberFormatter()
        numberFormatter.numberStyle = .decimal
        let number: NSNumber? = numberFormatter.number(from: self)
        
        guard let num = number else {
            return "-"
        }
        
        let formatter = NumberFormatter()
        
        formatter.positiveFormat = "###,##0.00"
        let result = formatter.string(from: num)
        
        return result == nil ? "" : (result ?? "")
    }
    
    /**
     整数每3位加一个逗号
     */
    func centryPriceFormat() -> String {
        
        var newStr = ""
        
        if self.contains(".") {
            
            // 拿到整数部分和小数部分
            let firstStr: String = self.components(separatedBy: ".").first ?? ""
            let secondStr: String = self.components(separatedBy: ".").last ?? ""
            
            // 存在.说明是小数整数
            for i in 1...firstStr.count {
                
                let index: Int = firstStr.count - i
                
                let subStr: String = firstStr.substring(index, length: 1) ?? ""
                
                if i % 3 == 0 && index != 0 {
                    newStr = ",".appending(subStr).appending(newStr)
                } else {
                    newStr = subStr.appending(newStr)
                }
            }
            
            newStr = newStr.appending(".").appending(secondStr)
            
        } else {
            
            // 不存在.说明是整数
            for i in 1...self.count {
                
                let index: Int = self.count - i
                
                let subStr: String = self.substring(index, length: 1) ?? ""
                
                if i % 3 == 0 && index != 0 {
                    newStr = ",".appending(subStr).appending(newStr)
                } else {
                    newStr = subStr.appending(newStr)
                }
            }
        }
        
        return newStr
    }
    
    /// 将正价字符串转成正价显示格式,例如: 55403.74 转成 55,403.74 并且小数点后面的数字的字体变小
    func getPriceAttrString(leftFont: UIFont, rightFont: UIFont) -> NSAttributedString {
        
        let resultStr = self
        
        // 将字符串转成attrStr
        let strs: [String] = resultStr.components(separatedBy: ".")
        
        let firstStr: String = strs.first ?? "-"
        
        if firstStr == "0" || strs.count == 1 {
            
            // 当前的数据小于1
            let firstAttrStr: NSMutableAttributedString = NSMutableAttributedString(string: "\(resultStr)", attributes: [NSAttributedString.Key.font : leftFont, NSAttributedString.Key.foregroundColor: UIColor.white])
            
            return firstAttrStr
        } else {
            
            // 当前的数据大于1
            let firstAttrStr: NSMutableAttributedString = NSMutableAttributedString(string: "\(strs.first ?? "-").", attributes: [NSAttributedString.Key.font : leftFont, NSAttributedString.Key.foregroundColor: UIColor.white])
            
            let secondAttrStr: NSAttributedString = NSAttributedString(string: "\(strs.last ?? "-")", attributes: [NSAttributedString.Key.font : rightFont, NSAttributedString.Key.foregroundColor: UIColor.white])
            
            firstAttrStr.append(secondAttrStr)
            
            return firstAttrStr
        }
    }
    
    /// 将制定的人民币字符串转成人民币显示格式,例如: 55403.74 转成 ¥55,403.74 并且小数点后面的数字的字体变小
    func getRMBAttrString1(leftFont: UIFont, rightFont: UIFont, textColor: UIColor) -> NSAttributedString {
        
        let resultStr = self
        
        // 将字符串转成attrStr
        let strs: [String] = resultStr.components(separatedBy: ".")
        
        //        let firstStr: String = strs.first ?? "-"
        
        if strs.count < 2 {
            
            // 当前的数据小于1
            let firstAttrStr: NSMutableAttributedString = NSMutableAttributedString(string: "¥", attributes: [NSAttributedString.Key.font : rightFont, NSAttributedString.Key.foregroundColor: textColor])
            
            let secondAttrStr: NSAttributedString = NSAttributedString(string: resultStr, attributes: [NSAttributedString.Key.font : leftFont, NSAttributedString.Key.foregroundColor: textColor])
            
            firstAttrStr.append(secondAttrStr)
            
            return firstAttrStr
        } else {
            
            // 当前的数据大于1
            let firstAttrStr: NSMutableAttributedString = NSMutableAttributedString(string: "¥", attributes: [NSAttributedString.Key.font : rightFont, NSAttributedString.Key.foregroundColor: textColor])
            
            let secondAttrStr: NSAttributedString = NSAttributedString(string: "\(strs.first ?? "-")", attributes: [NSAttributedString.Key.font : leftFont, NSAttributedString.Key.foregroundColor: textColor])
            
            let thirdAttrStr: NSAttributedString = NSAttributedString(string: ".\(strs.last ?? "-")", attributes: [NSAttributedString.Key.font : rightFont, NSAttributedString.Key.foregroundColor: textColor])
            
            firstAttrStr.append(secondAttrStr)
            firstAttrStr.append(thirdAttrStr)
            
            return firstAttrStr
        }
    }
    
    /// top100顶部的三个视图中的中间位,例如:¥78680亿，将亿字变小
    func getTop100IndexMidAttrString(textColor: UIColor) -> NSAttributedString {
        
        if self.count <= 1 {
            return NSAttributedString(string: "¥\(self)")
        }
        
        // 当字符串的长度大于1的时候，获取字符串最后一位，查看是否是“亿”或者“万”
        let lastStr = self.substring(self.count - 1, length: 1) ?? ""
        var secondAttrStr: NSAttributedString = NSAttributedString(string: "")
        if lastStr == kText("market_search_ten_thousand") || lastStr == kText("market_billion") {
            secondAttrStr = NSAttributedString(string: lastStr, attributes: [NSAttributedString.Key.font : FontAsset.PingFangSC_Regular.size(12.0), NSAttributedString.Key.foregroundColor: textColor])
        }
        
        let firstStr = self.substring(0, length: self.count - 1) ?? ""
        let firstAttrStr: NSMutableAttributedString = NSMutableAttributedString(string: "¥\(firstStr) ", attributes: [NSAttributedString.Key.font :FontAsset.DINAlternate_Bold.size(20.0), NSAttributedString.Key.foregroundColor: textColor])
        
        firstAttrStr.append(secondAttrStr)
        
        return firstAttrStr
    }
    
    /// top100顶部的三个视图中的最右边
    func getTop100IndexRightAttrString(textColor: UIColor) -> NSAttributedString {
        
        // 将字符串转成attrStr
        let strs: [String] = self.components(separatedBy: " ")
        
        let firstAttrStr: NSMutableAttributedString = NSMutableAttributedString(string: "\(strs.first ?? "-")", attributes: [NSAttributedString.Key.font : FontAsset.DINAlternate_Bold.size(20.0), NSAttributedString.Key.foregroundColor: textColor])
        
        let secondAttrStr: NSAttributedString = NSAttributedString(string: " \(strs.last ?? "-")", attributes: [NSAttributedString.Key.font : FontAsset.PingFangSC_Regular.size(14.0), NSAttributedString.Key.foregroundColor: textColor])
        
        firstAttrStr.append(secondAttrStr)
        
        return firstAttrStr
    }
    
    /// 获取制定字符的长度字符串，以英文为标准，数字为1个字符，中文为2个字符
    func getSubString(charCount: Int) -> String? {
        
        var result: String = ""
        var totalCount: Int = 0
        
        for (_, value) in self.enumerated() {
            
            var newCount: Int = 0
            
            if ("\u{4E00}" <= value  && value <= "\u{9FA5}") {
                newCount = 2
            } else {
                newCount = 1
            }
            
            if (totalCount + newCount) > charCount {
                return result
            }
            
            result.append(value)
            totalCount = totalCount + newCount
        }
        
        // 到了这里说明所有的字符加起来都没达到标准，输出所有的字符
        return self
    }
    
    /// 查看字符串是否小于等于指定字符个数，以英文为标准，数字为1个字符，中文为2个字符
    func isLessThenCharLength(charCount: Int) -> Bool {
        return self.getSubString(charCount: charCount) == self
    }
    
    /// 获取小数点后的位数
    func getLastCountAfterPoint() -> Int {
        
        // 首先判断传入的值能否转成数字，如果不能，则直接返回0
        guard let _ = Double(self) else {
            return 0
        }
        
        // 根据.拆分字符串，如果拆分后的数组个数不是2，直接返回0
        let arr: [String] = self.components(separatedBy: ".")
        guard arr.count == 2 else {
            return 0
        }
        
        return arr.last!.count
    }
    
    /// 图片字符串保护，这里如果有？，则将问号后面的都删除
    func getSafeUrlStr() -> String {
        if self.contains("?") {
            return self.components(separatedBy: "?").first ?? ""
        }
        
        return self
    }
    
    func analyseCnString() -> String {
        let charSet = CharacterSet.urlQueryAllowed as NSCharacterSet
        let mutSet = charSet.mutableCopy() as! NSMutableCharacterSet
        mutSet.addCharacters(in: "#")
        mutSet.addCharacters(in: "%")
        return self.addingPercentEncoding(withAllowedCharacters: mutSet as CharacterSet) ?? ""
    }
    func removeBothEndsSpaces() -> String {
        let tempSelf = self
        return tempSelf.trimmingCharacters(in: CharacterSet.whitespaces)
    }
    
    static func getNotificationLogKey() -> String{
        return "event7"
    }
    static func getWebSocketLogKey() -> String{
        return "event8"
    }
}

// MARK: - 正则校验
extension String {
    func nickname(isBindingWechat:Bool) -> String {
        if isBindingWechat {
            return self
        }
        if !self.isPhone() {
            return self
        }
        let prefix = self.substring(0, length: 3) ?? ""
        let suffix = self.substring(6, length: 4) ?? ""
        return prefix + "****" + suffix
    }
    func isEmail() -> Bool {
        let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"
        let emailTest = NSPredicate(format: "SELF MATCHES %@", emailRegex)
        return emailTest.evaluate(with: self)
    }
    
    func isPhone() -> Bool {
        let phoneRegex = "^1\\d{10}$"
        let phoneTest = NSPredicate(format: "SELF MATCHES %@", phoneRegex)
        return phoneTest.evaluate(with: self)
    }
    func isSmsCode() -> Bool {
        let phoneRegex = "^\\d{6}$"
        let phoneTest = NSPredicate(format: "SELF MATCHES %@", phoneRegex)
        return phoneTest.evaluate(with: self)
    }
    func getNumber() -> String {
        let scanner = Scanner(string: self)
        scanner.scanUpToCharacters(from: CharacterSet.decimalDigits, into: nil)
        var number :Int = 0
        scanner.scanInt(&number)
        dPrintLog(number)
        return String(number)
    }
    func isImagePath() -> Bool {
        if self.lowercased().hasSuffix(".jpg") {
            return true
        }
        return false
    }
    func isVideoPath() -> Bool {
        if self.lowercased().hasSuffix(".mp4") {
            return true
        }
        return false
    }
    func isIdentityNo() -> Bool{
        if self.count <= 0 {
            return false
        }
        return true
    }
}

// MARK: - 加密
extension String{
    
    var md5: String {
        let cStr = self.cString(using: String.Encoding.utf8);
        let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: 16)
        CC_MD5(cStr!,(CC_LONG)(strlen(cStr!)), buffer)
        let md5String = NSMutableString();
        for i in 0 ..< 16{
            md5String.appendFormat("%02x", buffer[i])
        }
        free(buffer)
        return md5String as String
    }
}

extension String {
    var decimal: NSDecimalNumber {
        let de = NSDecimalNumber.init(string: self)
        
        return de == NSDecimalNumber.notANumber ? NSDecimalNumber.init(string: "0") : de
    }
    func sizeWithConstrainedSize(size:CGSize, font:UIFont, lineSpacing:CGFloat) -> CGSize{
        var expectedSize = CGSize.zero
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineBreakMode = NSLineBreakMode.byWordWrapping
        paragraphStyle.lineSpacing = lineSpacing
        let attributes = [
            NSAttributedString.Key(rawValue: NSAttributedString.Key.font.rawValue):  font, NSAttributedString.Key.paragraphStyle : paragraphStyle
            ] as [NSAttributedString.Key : Any]
        
        expectedSize = self.boundingRect(with: size, options: NSStringDrawingOptions(rawValue: NSStringDrawingOptions.RawValue(UInt8(NSStringDrawingOptions.usesLineFragmentOrigin.rawValue) |
            UInt8(NSStringDrawingOptions.usesFontLeading.rawValue))), attributes: attributes , context: nil).size
        return CGSize(width: ceil(expectedSize.width), height: ceil(expectedSize.height))
    }
}

extension NSMutableAttributedString {
}
extension NSString {
    @objc func isVideoPath() -> Bool {
        let tempSelf = self
        return  tempSelf.hasSuffix(".mp4") ||
                tempSelf.hasSuffix(".mov") ||
                tempSelf.hasSuffix(".flv") ||
                tempSelf.hasSuffix(".3gp") ||
                tempSelf.hasSuffix(".avi") ||
                tempSelf.hasSuffix(".rm")  ||
                tempSelf.hasSuffix(".wmv")
    }
}

extension String {
    func oss(h:CGFloat,w:CGFloat) -> String {
        if self.length <= 0 {
            return ""
        }
        return "\(self)?x-oss-process=image/resize,m_fixed,h_\(h),w_\(w)"
    }
    func oss() -> String {
        if self.length <= 0 {
            return ""
        }
        return "\(self)?x-oss-process=image/resize,m_fixed,h_150,w_150"
    }
    
    func oss_level01() -> String {
        if self.length <= 0 {
            return ""
        }
        return "\(self)?x-oss-process=image/resize,m_fixed,h_500,w_500"
    }
}
//192.168.99.190/192.168.2.25
func getHost()->String{
    return "192.168.2.25"//"192.168.0.102"//
}


extension String {
    func toJson() -> [String:Any]{
        let tempSelf = self
        let jsonData:Data = tempSelf.data(using: .utf8) ?? Data()
        let dict = try? JSONSerialization.jsonObject(with: jsonData, options: .mutableContainers)
        if let tempDict = dict as? [String:Any] {
            return tempDict
        }
        return [:]
    }
    //将原始的url编码为合法的url
    func urlEncoded() -> String {
        let encodeUrlString = self.addingPercentEncoding(withAllowedCharacters:
            .urlQueryAllowed)
        return encodeUrlString ?? ""
    }
    //将编码后的url转换回原始的url
    func urlDecoded() -> String {
        return self.removingPercentEncoding ?? ""
    }
    
    func urlPath() -> String {
        let arr = self.components(separatedBy: "?")
        return arr.first ?? ""
    }
    
    // 获取参数
    func params() -> [String:Any] {
        guard let tempUrl = URL(string: self.analyseCnString()) else {
            return [:]
        }
        var params:[String:Any] = [:]
        guard let queryItems = URLComponents(url: tempUrl, resolvingAgainstBaseURL: true)?.queryItems else {
            return params
        }
        queryItems.forEach { (item) in
            let key = item.name
            let value = item.value
            params[key] = value
        }
        return params
    }
    
    
    func cx_urlQueryDict() -> [String:Any] {
        var params:[String:Any] = [:]
        guard let queryItems = URLComponents(string: self)?.queryItems else {
            return params
        }
        queryItems.forEach { (item) in
            let key = item.name
            let value = item.value
            params[key] = value
        }
        return params
    }
    func cx_pattern() -> String {
        let anasyleUrl = self.components(separatedBy: "?")
        if anasyleUrl.count <= 1 {
            return self
        }
        return anasyleUrl[0]
    }
    func cx_append(params:[String:Any]) -> String{
        var tempStirng = self
        if params.count <= 0 {
            return tempStirng
        }
        if !tempStirng.contains("?") {
            tempStirng += "?"
        }else{
            tempStirng += "&"
        }
        for (index,item) in params.enumerated() {
            let key = item.key
            let value = item.value
            guard let valueString = String.SwitchToString(value) else { continue }
            tempStirng += "\(key)=\(valueString)"
            if index + 1 < params.count {
                tempStirng += "&"
            }
        }
        return tempStirng
    }
}

extension String {

    //MARK: -传进去字符串,生成二维码图片
    func setupQRCodeImage( image: UIImage?) -> UIImage {
        let urlPath = self
        //创建滤镜
        let filter = CIFilter(name: "CIQRCodeGenerator")
        filter?.setDefaults()
        //将url加入二维码
        filter?.setValue(urlPath.data(using: String.Encoding.utf8), forKey: "inputMessage")
        //取出生成的二维码（不清晰）
        if let outputImage = filter?.outputImage {
            //生成清晰度更好的二维码
            let qrCodeImage = setupHighDefinitionUIImage(outputImage, size: 300)
            //如果有一个头像的话，将头像加入二维码中心
            if var image = image {
                //给头像加一个白色圆边（如果没有这个需求直接忽略）
                image = circleImageWithImage(image, borderWidth: 50, borderColor: UIColor.white)
                //合成图片
                let newImage = syntheticImage(qrCodeImage, iconImage: image, width: 100, height: 100)
                
                return newImage
            }
            
            return qrCodeImage
        }
        
        return UIImage()
    }

    //image: 二维码 iconImage:头像图片 width: 头像的宽 height: 头像的宽
    func syntheticImage(_ image: UIImage, iconImage:UIImage, width: CGFloat, height: CGFloat) -> UIImage{
        //开启图片上下文
        UIGraphicsBeginImageContext(image.size)
        //绘制背景图片
        image.draw(in: CGRect(origin: CGPoint.zero, size: image.size))
        
        let x = (image.size.width - width) * 0.5
        let y = (image.size.height - height) * 0.5
        iconImage.draw(in: CGRect(x: x, y: y, width: width, height: height))
        //取出绘制好的图片
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        //关闭上下文
        UIGraphicsEndImageContext()
        //返回合成好的图片
        if let newImage = newImage {
            return newImage
        }
        return UIImage()
    }

    //MARK: - 生成高清的UIImage
    func setupHighDefinitionUIImage(_ image: CIImage, size: CGFloat) -> UIImage {
        let integral: CGRect = image.extent.integral
        let proportion: CGFloat = min(size/integral.width, size/integral.height)
        
        let width = integral.width * proportion
        let height = integral.height * proportion
        let colorSpace: CGColorSpace = CGColorSpaceCreateDeviceGray()
        let bitmapRef = CGContext(data: nil, width: Int(width), height: Int(height), bitsPerComponent: 8, bytesPerRow: 0, space: colorSpace, bitmapInfo: 0)!
        
        let context = CIContext(options: nil)
        let bitmapImage: CGImage = context.createCGImage(image, from: integral)!
        
        bitmapRef.interpolationQuality = CGInterpolationQuality.none
        bitmapRef.scaleBy(x: proportion, y: proportion);
        bitmapRef.draw(bitmapImage, in: integral);
        let image: CGImage = bitmapRef.makeImage()!
        return UIImage(cgImage: image)
    }

    //生成边框
    func circleImageWithImage(_ sourceImage: UIImage, borderWidth: CGFloat, borderColor: UIColor) -> UIImage {
        let imageWidth = sourceImage.size.width + 2 * borderWidth
        let imageHeight = sourceImage.size.height + 2 * borderWidth
        
        UIGraphicsBeginImageContextWithOptions(CGSize(width: imageWidth, height: imageHeight), false, 0.0)
        UIGraphicsGetCurrentContext()
        
        let radius = (sourceImage.size.width < sourceImage.size.height ? sourceImage.size.width:sourceImage.size.height) * 0.5
        let bezierPath = UIBezierPath(arcCenter: CGPoint(x: imageWidth * 0.5, y: imageHeight * 0.5), radius: radius, startAngle: 0, endAngle: .pi * 2, clockwise: true)
        bezierPath.lineWidth = borderWidth
        borderColor.setStroke()
        bezierPath.stroke()
        bezierPath.addClip()
        sourceImage.draw(in: CGRect(x: borderWidth, y: borderWidth, width: sourceImage.size.width, height: sourceImage.size.height))
        
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image!
    }
}
